﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace SMTP.Test.Client.Requests
{
    public static class RequestUtility
    {
        public static bool IsIPAddress(this string address)
        {
            Regex IpMatch = new Regex(@"\b(?:\d{1,3}\.){3}\d{1,3}\b");
            return IpMatch.IsMatch(address);
        }

        public static IPAddress GetIPAddress(this string address)
        {
            IPAddress addr = null;
            try
            {
                if (address.IsIPAddress())
                {
                    addr = IPAddress.Parse(address);
                }
                else
                {
                    IPHostEntry hostEntry = address.GetIPHostEntry();

                    if ((hostEntry != null) && (hostEntry.AddressList.Count() > 0))
                    {
                        addr = hostEntry.AddressList[0];
                    }
                }
            }
            catch 
            {
                //do nothing...just here to ensure program stays functional
            }

            return addr;
        }

        public static IPHostEntry GetIPHostEntry(this string address)
        {
            IPHostEntry hostEntry = null;
            try
            {
                hostEntry =  Dns.GetHostEntry(address);
            }
            catch
            { 
                //do nothing...just here to ensure program stays functional
            }

            return hostEntry;
        }


        public static bool ScanPort(this string address, int port)
        {
            const int TIMEOUT = 2000;
            bool connected = false;

            try
            {
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IAsyncResult results = socket.BeginConnect(address, port, null, null);
                connected = results.AsyncWaitHandle.WaitOne(TIMEOUT, true);

                Task.Factory.StartNew(() =>
                {
                    socket.Close();
                });
            }
            catch
            {
            }

            return connected;
        }

        public static bool ScanPort(this string address, int port, int timeout)
        {
            bool connected = false;

            try
            {
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IAsyncResult results = socket.BeginConnect(address, port, null, null);
                connected = results.AsyncWaitHandle.WaitOne(timeout, true);

                Task.Factory.StartNew(() =>
                {
                    socket.Close();
                });
               
            }
            catch
            {
            }

            return connected;
        }
    }
}
